import { between, cloneObject } from '@/lib/util'
import { eventBus, logger } from '@/instance'
import { ref, reactive, computed, ComputedRef, Ref, inject } from 'vue'
import { StyleBinding, Btn } from '@/types'
import { defaultClipBtns } from '@/constants/btns'
import { Clip } from '@/core/clip'
import { Track } from '@/core/track'
import { updateClip } from '@/console/storyboard'

export type ClipComposition = {
  style: ComputedRef<StyleBinding>
  handleResizeStart: () => void
  handleResized: () => void
  handleResizing: (type: 'left' | 'right', movement: number) => void
  btns: ComputedRef<Btn[]>
  leftMovementRange: ComputedRef<[number, number]>
  rightMovementRange: ComputedRef<[number, number]>
  handleBtnClick: (btn: Btn) => void
}

export function useClip(
  clip: Clip,
  defaultStyle: Ref<{ left: number; width: number }>
): ClipComposition {
  let resizingStyle = reactive({ ...defaultStyle.value })
  let resizing = ref(false)

  const storyboard = inject('storyboard') as Track
  console.log()
  const style = computed(() => {
    let s = resizing.value ? resizingStyle : defaultStyle.value
    return {
      left: s.left + 'px',
      width: s.width + 'px',
    }
  })
  let shadowClip = ref(cloneObject(clip))
  const handleResized = () => {
    resizing.value = false
    resizingStyle = reactive({ ...defaultStyle.value })
    shadowClip.value = cloneObject(clip)
  }
  const handleResizeStart = () => {
    resizing.value = true
    shadowClip.value = cloneObject(clip)
  }
  const handleResizing = (type: 'left' | 'right', movement: number) => {
    logger.log('composables/storyboard', 'clip', type, movement)
    // 修改style and duration
    handleUpdateStyle(type, movement)
    handleUpdateClip(type, movement)
  }

  const handleUpdateStyle = (type: 'left' | 'right', movement: number) => {
    switch (type) {
      case 'left':
        resizingStyle.left = defaultStyle.value.left + movement
        resizingStyle.width = defaultStyle.value.width - movement
        break
      case 'right':
        resizingStyle.width = defaultStyle.value.width + movement
        break
    }
  }
  const handleUpdateClip = (type: 'left' | 'right', movement: number) => {
    const timeMovement = (movement / 240) * shadowClip.value.duration
    switch (type) {
      case 'left':
        // 修改in duration
        clip.duration = between(
          shadowClip.value.duration - timeMovement,
          0.03,
          shadowClip.value.ref?.length || Infinity
        )
        if (clip.ref) {
          clip.ref.in =
            shadowClip.value.ref!.in -
            (clip.duration - shadowClip.value.duration)
        }
        clip.offset =
          shadowClip.value.offset - (clip.duration - shadowClip.value.duration)
        break

      case 'right':
        // 修改duration
        clip.duration = between(
          shadowClip.value.duration + timeMovement,
          0.03,
          shadowClip.value.ref?.length || Infinity
        )
        if (clip.ref) {
          clip.ref.out = between(
            shadowClip.value.duration + timeMovement,
            0.03,
            shadowClip.value.ref?.length || Infinity
          )
        }
        break

      default:
        break
    }
    updateClip(storyboard, clip)
  }

  const btns = computed(() => {
    logger.log('composables/storyboard/clip', 'btnsComputed')
    return defaultClipBtns as Array<Btn>
  })
  const handleBtnClick = (btn: Btn) => {
    const action = btn.id
    eventBus.emit(action, { clip: clip, track: storyboard })
    logger.log('composables/storyboard/clip', 'handleBtnClick', action, btn)
  }

  const leftMovementRange = computed<[number, number]>(() => {
    const pxPerSec = 240 / shadowClip.value.duration
    return [
      -(shadowClip.value.ref?.in || 0) * pxPerSec,
      shadowClip.value.duration * pxPerSec,
    ]
  })
  const rightMovementRange = computed<[number, number]>(() => {
    const pxPerSec = 240 / shadowClip.value.duration
    return [
      -shadowClip.value.duration * pxPerSec,
      ((shadowClip.value.ref?.length || 0) - (shadowClip.value.ref?.out || 0)) *
        pxPerSec,
    ]
  })
  return {
    style,
    handleResized,
    handleResizeStart,
    handleResizing,
    leftMovementRange,
    rightMovementRange,
    btns,
    handleBtnClick,
  }
}
